from flask import Flask, render_template, request, redirect, url_for, session, jsonify
from database import db
from weather_api import WeatherAPI  # 导入类
weather_api = WeatherAPI()  # 自己创建实例
from datetime import datetime
import functools
import json
from apscheduler.schedulers.background import BackgroundScheduler
import atexit
from flask_socketio import SocketIO
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.secret_key = 'your_secret_key_here'  

# 修改SocketIO初始化
socketio = SocketIO(
    app,
    async_mode='eventlet',  # 在此处指定async_mode
    cors_allowed_origins="*"  # 如果需要跨域
)

# 修改WebSocket命名空间为统一路径
@socketio.on('connect', namespace='/alerts')
def handle_connect():
    print(f'[WebSocket] 客户端连接: {request.sid}')
    
    # 推送历史未读消息
    latest = db.get_latest_emergency_response()
    if latest and 'is_pushed' in latest and not latest['is_pushed']:
        emit('new_alert', {
            'content': latest['content'],
            'timestamp': latest['timestamp'].strftime('%Y-%m-%d %H:%M')
        })
        db.mark_as_pushed(latest['id'])

@socketio.on('disconnect', namespace='/alerts')
def handle_disconnect():
    print(f'[WebSocket] 客户端断开: {request.sid}')


# 初始化调度器
scheduler = BackgroundScheduler()
scheduler.start()
atexit.register(lambda: scheduler.shutdown())  # 程序退出时关闭调度器

# 登录装饰器
def login_required(role=None):
    def decorator(f):
        @functools.wraps(f)
        def decorated_function(*args, **kwargs):
            if 'user_id' not in session:
                return redirect(url_for('login'))
            if role and session.get('role') != role:
                return redirect(url_for('index'))
            return f(*args, **kwargs)
        return decorated_function
    return decorator

@app.route('/')
def index():
    """主页面"""
    if 'user_id' in session:
        if session['role'] == 'admin':
            return redirect(url_for('admin_dashboard'))
        elif session['role'] == 'rescuer':
            return redirect(url_for('rescuer_dashboard'))
        else:
            return redirect(url_for('user_dashboard'))
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    """登录页面"""
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        user = db.get_user(username)
        if user and user['password'] == password:
            session['user_id'] = user['id']
            session['username'] = user['username']
            session['role'] = user['role']
            return redirect(url_for('index'))
        else:
            return render_template('login.html', error='用户名或密码错误')
    
    return render_template('login.html')

@app.route('/logout')
def logout():
    """登出"""
    session.clear()
    return redirect(url_for('index'))

@app.route('/register', methods=['GET', 'POST'])
def register():
    """注册页面"""
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        role = request.form['role']
        
        # 检查用户名是否已存在
        if db.get_user(username):
            return render_template('register.html', error='用户名已存在')
        
        # 添加新用户
        if db.add_user(username, password, role):
            return redirect(url_for('login'))
        else:
            return render_template('register.html', error='注册失败，请重试')
    
    return render_template('register.html')

@app.route('/admin')
@login_required(role='admin')
def admin_dashboard():
    """管理员仪表板"""
    return render_template('admin.html')

@app.route('/admin/get_weather', methods=['GET'])
@login_required(role='admin')
def admin_get_weather():
    """管理员获取天气信息"""
    warnings = weather_api.get_weather_warnings()
    if warnings['status'] == 'success':
        # 保存到数据库
        db.add_weather_warning(weather_api.location_id, json.dumps(warnings['data']))
        
        # 添加更多调试信息
        app.logger.info(f"获取到天气预警数据: {warnings}")
        
    return jsonify(warnings)

@app.route('/admin/send_response', methods=['POST'])
@login_required(role='admin')
def admin_send_response():
    """管理员发送应急响应信息"""
    content = request.form.get('content')
    if content:
        db.add_emergency_response(content, session['user_id'])
        return jsonify({'status': 'success'})
    return jsonify({'status': 'error', 'message': '内容不能为空'})

@app.route('/admin/get_users')
@login_required(role='admin')
def admin_get_users():
    """管理员获取用户列表"""
    users = db.get_all_users('user')
    return jsonify(users)

@app.route('/admin/get_rescuers')
@login_required(role='admin')
def admin_get_rescuers():
    """管理员获取救援人员列表"""
    rescuers = db.get_all_users('rescuer')
    return jsonify(rescuers)

@app.route('/admin/get_help_requests')
@login_required(role='admin')
def admin_get_help_requests():
    """管理员获取求救信息"""
    requests = db.get_all_help_requests()
    return jsonify(requests)

@app.route('/admin/send_to_rescuer', methods=['POST'])
@login_required(role='admin')
def admin_send_to_rescuer():
    """管理员发送消息给救援人员"""
    rescuer_id = request.form.get('rescuer_id')
    content = request.form.get('content')
    
    if rescuer_id and content:
        db.add_message(session['user_id'], rescuer_id, content)
        return jsonify({'status': 'success'})
    return jsonify({'status': 'error', 'message': '救援人员ID或内容不能为空'})

@app.route('/admin/get_rescuer_replies')
@login_required(role='admin')
def admin_get_rescuer_replies():
    """管理员获取救援人员回复"""
    replies = db.get_messages_for_user(session['user_id'])
    return jsonify(replies)

@app.route('/user')
@login_required(role='user')
def user_dashboard():
    """用户仪表板"""
    return render_template('user.html')

@app.route('/user/get_weather')
@login_required(role='user')
def user_get_weather():
    """用户获取天气信息"""
    warning = db.get_latest_weather_warning(weather_api.location_id)
    if warning:
        return jsonify({
            'status': 'success',
            'data': json.loads(warning['warning_data']),
            'timestamp': warning['timestamp'].strftime('%Y-%m-%d %H:%M:%S')
        })
    return jsonify({'status': 'no_warning', 'message': '没有天气预警信息'})

@app.route('/user/get_response')
@login_required(role='user')
def user_get_response():
    """用户获取应急响应信息"""
    response = db.get_latest_emergency_response()
    if response:
        return jsonify({
            'status': 'success',
            'content': response['content'],
            'admin_name': response['admin_name'],
            'timestamp': response['timestamp'].strftime('%Y-%m-%d %H:%M:%S')
        })
    return jsonify({'status': 'no_response', 'message': '没有应急响应信息'})

@app.route('/user/send_help', methods=['POST'])
@login_required(role='user')
def user_send_help():
    """用户发送求救信息"""
    content = request.form.get('content')
    if content:
        db.add_help_request(session['user_id'], content)
        return jsonify({'status': 'success'})
    return jsonify({'status': 'error', 'message': '内容不能为空'})

@app.route('/rescuer')
@login_required(role='rescuer')
def rescuer_dashboard():
    """救援人员仪表板"""
    return render_template('rescuer.html')

@app.route('/rescuer/get_admin_messages')
@login_required(role='rescuer')
def rescuer_get_admin_messages():
    """救援人员获取管理员消息"""
    admin = db.get_user('admin')
    if admin:
        messages = db.get_messages_for_user(session['user_id'], admin['id'])
        return jsonify(messages)
    return jsonify([])

@app.route('/rescuer/reply_to_admin', methods=['POST'])
@login_required(role='rescuer')
def rescuer_reply_to_admin():
    """救援人员回复管理员"""
    content = request.form.get('content')
    admin = db.get_user('admin')
    
    if content and admin:
        db.add_message(session['user_id'], admin['id'], content)
        return jsonify({'status': 'success'})
    return jsonify({'status': 'error', 'message': '内容不能为空'})



def check_and_notify_weather():
    """定时检查天气并推送通知"""
    with app.app_context():
        print("[定时任务] 正在检查天气预警...")
        result = weather_api.get_weather_warnings()
        
        if result['status'] == 'success' and result['data']:
            admin = db.get_user('admin')
            if admin:
                # 构建预警消息内容
                warning_msg = "\n".join(
                    f"【{w.get('typeName', '天气')}预警】{w.get('text', '')}" 
                    for w in result['data']
                )
                
                # 保存到数据库
                warning_id = db.add_emergency_response(
                    content=warning_msg,
                    admin_id=admin['id'],
                    is_auto=True
                )
                
                # 实时推送给所有客户端
                socketio.emit('new_alert', {
                    'content': warning_msg,
                    'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                }, namespace='/alerts')
                
                print(f"[定时任务] 已推送预警: {warning_msg}")

# 添加定时任务
scheduler.add_job(
    func=check_and_notify_weather,
    trigger='interval',
    minutes=10,  # 每10分钟检查一次
    id='weather_monitor'
)


if __name__ == '__main__':
    socketio.run(
        app,
        host='127.0.0.1',  # 改为明确地址
        port=5000,
        debug=True
    )